package Persistencia;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class BDMConexion {
    
    private static BDMConexion instance = null;
    private final static String drv = "org.sqlite.JDBC";
    private String direccionBD = null;
    private String db = "jdbc:sqlite:";
    private Connection ct = null;
    private PreparedStatement ps = null;
    private Statement st = null;
    private ResultSet rs = null;

    //CONSTRUCTOR
    
    private BDMConexion(String direccionBD) throws Exception{
        
        this.direccionBD = direccionBD;
        this.db = this.db.concat(this.direccionBD);
        
    }
    
    public void abrirConexion(Object Caller) throws Exception {
        
        //System.out.println((String) Caller);
        
        try{
        
            if(ct != null){
                
                
                
                while(!ct.isClosed()){

                    esperar(100);
                    
                }

                Class.forName(drv);
                ct = DriverManager.getConnection(db);
                   
            }

            else{
            
                Class.forName(drv);
                ct = DriverManager.getConnection(db);
            
            }
            
        }
        
        catch(ClassNotFoundException | SQLException e){
        
            throw e;
        
        }
        
        //System.out.println("Abri");
        
    }
    
    private void esperar(Integer tiempo) throws Exception{
    
        Thread.sleep(tiempo);
    
    }
    
    public void cerrarConexion() throws Exception {
    
        try{
        
            ct.close();
    
        }
        
        catch(Exception e){
        
            throw e;
        
        }
        
        //System.out.println("Cerre");
            
    }
    
    //GETERS
    
    public static synchronized BDMConexion getInstance(String direccionBD) throws Exception{
        
        if(instance == null){
            
            instance = new BDMConexion(direccionBD);
        
        }
        
        return instance;
    
    }
    
    public Connection getConexion() throws Exception{
                    
        return ct;
    
    }
    
    private String getEsquemaPath(String direccionBD){
    
        String esquemaPath = direccionBD.substring(0, direccionBD.lastIndexOf(File.separatorChar));
                
        return esquemaPath;
    
    }
    
    public void limpiarBD() throws Exception{
    
        try{
        
            String path = getEsquemaPath(direccionBD) + "/Esquema.sql";
            File f = new File(path);
            FileReader fr = new FileReader(f);
            BufferedReader br = new BufferedReader(fr);
            
            String sql = new String();
            String linea;
            
            while((linea = br.readLine()) != null){
            
                sql = sql.concat(linea);
            
            }
            
            st = ct.createStatement();
            st.executeUpdate(sql);
            br.close();
            
                                  
        } 
        
        catch(IOException | SQLException e){
        
            throw new Exception(e.getMessage());
        
        }
                
    }
    
    
    //Funcion para cargar datos de prueba desde script sql
    public void cargarBD() throws Exception{
    
        try{
        
            String path = getEsquemaPath(direccionBD) + "/datos.sql";
            File f = new File(path);
            FileReader fr = new FileReader(f);
            BufferedReader br = new BufferedReader(fr);
            
            String sql = new String();
            String linea;
            
            while((linea = br.readLine()) != null){
            
                sql = sql.concat(linea);
            
            }
            
            st = ct.createStatement();
            st.executeUpdate(sql);
            br.close();
            
                                  
        } 
        
        catch(IOException | SQLException e){
        
            throw new Exception(e.getMessage());
        
        }
                
    }
    
    
    public Boolean esVacia() throws Exception{
    
        Boolean vacia = null;
        
        try{
        
            ps = ct.prepareStatement("SELECT NOT EXISTS(SELECT 1 FROM clientes, desarrolladores, juegos, categorias, comentarios)");
            rs = ps.executeQuery();
                    
            vacia = rs.getBoolean(1);
            
        } 
        
        catch(SQLException e){
        
            throw new Exception(e.getMessage());
        
        }
        
        return vacia;
    
    }
    
}
